Frontend Forever App
We have a mobile app for you to download and use. And you can unlock many features in the app.
Get it now
Intall Later
Run
HTML
CSS
Javascript
Output
Document
Cyber Wolf
Flying cars
Flying cars 2
Flying cars 3
Cyber T-Rex
Cyber Raptor
Cyber freeway
@charset "UTF-8"; @import url(https://fonts.googleapis.com/css?family=Nunito+Sans:300,400,600,700,800); *, :after, :before { box-sizing: border-box; padding: 0; margin: 0; } @import "https://unpkg.com/open-props/easings.min.css"; @layer demo.view-transition { ::view-transition-group(*) { animation-duration: .5s; animation-timing-function: var(--ease-5); } .hub > * { @media (prefers-reduced-motion: no-preference) { &:nth-child(1) { view-transition-name: gallery-item-1; } &:nth-child(2) { view-transition-name: gallery-item-2; } &:nth-child(3) { view-transition-name: gallery-item-3; } &:nth-child(4) { view-transition-name: gallery-item-4; } &:nth-child(5) { view-transition-name: gallery-item-5; } &:nth-child(6) { view-transition-name: gallery-item-6; } &:nth-child(7) { view-transition-name: gallery-item-7; } } } @layer demo.layout { .hub { display: grid; gap: 1rem; grid-template-columns: repeat(5, 15vw); grid-template-rows: repeat(3, 15vw); &.portrait { grid-template-columns: repeat(3, 20vw); grid-template-rows: repeat(5, 20vw); } /* selected promotion */ > :has(:checked) { grid-column: 1 / 4; grid-row: 1 / 4; } /* pile the label, input and image */ > * { display: grid; > * { grid-area: 1/1; } > label { opacity: 0; cursor: pointer; -webkit-tap-highlight-color: transparent; } > input { border-radius: 0; outline-offset: 5px; outline-color: deeppink; outline-color: color(display-p3 1 0 1); } } } } @layer demo.support { * { box-sizing: border-box; margin: 0; } html { block-size: 100%; color-scheme: dark light; } body { min-block-size: 100%; font-family: system-ui, sans-serif; display: grid; place-content: center; } fieldset { border: none; padding: 0; margin: 0; } img { max-inline-size: 100%; } html { view-transition-name: none; } }
console.log("Event Fired") // watch for radio group input clicks // if VT is supported, prevent the default behavior // call VT and manually set checked document.querySelectorAll('#gallery input').forEach(radio => { radio.onclick = e => { if (!document.startViewTransition) return e.preventDefault() function mutate() { // radio group naturally handled unchecking the current one e.target.checked = true // reset the zindex so the next item can be on top e.target.parentNode.style.zIndex = null } // ensures selected item is on top during view transition e.target.parentNode.style.zIndex = 2 // always mutate, but VT if possible document.startViewTransition ? document.startViewTransition(() => mutate()) : mutate() } }) // function to handle device rotation / page resize function flipGallery() { function mutate(vertical = false) { if (document.startViewTransition) document.startViewTransition(() => vertical ? gallery.classList.add('portrait') : gallery.classList.remove('portrait')) } mutate(window.innerWidth <= 768) } // throttled resize observer // waits for 100ms of no resizing before firing flipGallery() window.onresize = () => { clearTimeout(window.resizeEndTimer) window.resizeEndTimer = setTimeout(flipGallery, 100) }